跨來源資源共用(Cross-Origin Resource Sharing (CORS))是一種使用額外 HTTP 標頭令目前瀏覽網站的使用者代理 (en-US)取得存取其他來源(網域)伺服器特定資源權限的機制。當使用者代理請求一個不是目前文件來源——例如來自於不同網域(domain)、通訊協定(protocol)或通訊埠(port)的資源時,會建立一個跨來源 HTTP 請求(cross-origin HTTP request)。
以上是MDN對CORS的說明
白話來理解就是:當你在訪問一個網站時,該網站的(圖片、資料或是腳本)不是存在於同一個伺服器上,這時候瀏覽器就會幫我們建立一個HTTP的跨域請求(cross-origin HTTP request)。
例如:在A網站要放入一張來源在B網站的圖片
<img src="http://domain-b.com/image.jpg">
如果沒有CORS,瀏覽器的同源政策會阻止這個跨來源的請求發生,來保護使用者的資訊安全。
The same-origin policy is a critical security mechanism that restricts how a document or script loaded by one origin can interact with a resource from another origin.
白話理解就是:確保一個網站的資源不能隨便干涉或使用來自另一個網站的資料或功能,它是為了保護你的資料不被其他不相干的網站訪問或濫用。
如果沒有了這層防護,有可能你的私密帳號資訊就會被竊取,或是你的社群被有心人士隨意登入,蠻可怕的。
「同源」指的是以下這三個部分:
scheme、domain、port 一樣就會被視為同源 (same-origin),其他則是不同源
舉例有一個網址是:https://al.com
http://al.com → 不同源 scheme 不同
https://al.com/payment → 同源
https://news.al.com → 不同源 domain 不同
https://al.com:81 → 不同源 port 不同
https://cl.com → 不同源 domain 不同
在大部分的情況下,我們不能認為所有網域都是有害的,而且在一間公司內做的項目很常會需要串接API,例如google map、第三方登入或是其他公開的API
CORS主要是在http的header來進行運作的,另外要分為前端與後端分別需要做的事情,大部分的設定都是在伺服器端完成,所以前端開發者只需要了解其基本概念和如何檢查response headers。
CORS分成「簡單請求(Simple requests)」以及「預檢請求(Preflighted requests)」
基本上都會是「預檢請求」,除非包含了基本請求的條件,例如fetch中的(GET/POST/HEAD)或是設定header、Content-Type等..這列會被列在「簡單請求」(詳細的簡單請求規範可以參考看看MDN)
預檢請求(Preflighted requests):
當我們用像是fetch的(PUT/DELETE/PATCH)或XMLHttpRequest來存取資料時,瀏覽器都會先發送一個「預檢請求」(preflight request)。
這個請求的目的是確認伺服器端是否有正確設定允許跨網域的 HTTP 標頭,當這個檢查通果後,真正的請求才會被發送。
(預檢請求的條件可以參考MDN)
舉例:
fetch('https://domainA.com/data/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
瀏覽器會先發出這樣的預檢請求
OPTIONS /data/
Host: domainA.com
Origin: https://myweb.com/
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
這個預檢請求就會像這樣跟伺服器說:「嗨~我現在要發送一個POST的請求,帶上Headers為Content-type,你可以接受嗎?」
如果伺服器接受,真正的請求就會被發送出去
因為Headers大部分會由後端人員來設定,當遇到 CORS 問題時,請後端工程師設定,要做的設定就是 Access-Control-Allow-Origin 的設定,範例如下
// 如果要允許所有跨域來源的請求,可以用星號
Access-Control-Allow-Origin:*
// 如果要允許特定來源的跨域請求,可以直接放入該來源
Access-Control-Allow-Origin: https://domainA.com
參考資料
MDN
簡單弄懂同源政策 (Same Origin Policy) 與跨網域 (CORS)
淺談跨來源資源共用(CORS)與解決辦法